package org.yagnus.yadoop
import org.apache.hadoop.fs.Path
import org.apache.hadoop.io._
import scala.collection.mutable.IndexedSeqView;

/**
 * The idea of using implicit to simplify implementing hadoop using scala came from a package called SHadoop on google code.
 * 
 * Some improvements, renaming, and corruption has occurred since. This package is developed with the express purpose of
 * support Yagnus's hzip project. 
 * 
 * @author hc.busy
 *
 */
object Yadoop {

    //TODO rewrite Write BytesWritable to take TraversableOnce[Byte], because below would still perform a copy on any slices we pass in.
    implicit def __b2bw(value : TraversableOnce[Byte]) = { new BytesWritable(value.toArray); }

    implicit def __intArrayWritable2IntArray(value : IntArrayWritable) = value.get;
    implicit def __intArray2IntArrayWritable(values : Array[Int]) : IntArrayWritable = new IntArrayWritable(values);

    implicit def __longArrayWritable2LongArray(value : LongArrayWritable) : Array[Long] = value.get;
    implicit def __longArray2LongArrayWritable(values : Array[Long]) : LongArrayWritable = new LongArrayWritable(values);

    implicit def __w2i(value : IntWritable) = value.get
    implicit def __i2w(value : Int) = new IntWritable(value)

    implicit def __w2l(value : LongWritable) = value.get
    implicit def __l2w(value : Long) = new LongWritable(value)
    implicit def __w2b(value : BooleanWritable) = value.get
    implicit def __b2w(value : Boolean) = new BooleanWritable(value)

    implicit def __w2f(value : FloatWritable) = value.get
    implicit def __f2w(value : Float) = new FloatWritable(value)

    implicit def __t2s(value : Text) = value.toString
    implicit def __s2t(value : String) = new Text(value)

    implicit def __u82s(value : UTF8) = value.toString
    implicit def __s2u8(value : String) = new UTF8(value)

    implicit def __path2string(value : Path) = value.toString
    implicit def __string2path(value : String) = new Path(value)

    implicit def __b2bw(value : Array[Byte]) = new BytesWritable(value);

    implicit def __javaIterator2ScalaIterator[A](itr : java.util.Iterator[A]) = new scala.collection.Iterator[A] {
        def hasNext = itr.hasNext;
        def next = itr.next;
    }

    implicit def __bw2b(value : BytesWritable) : Array[Byte] = value.getBytes;

    /***
     * For the people who got bit with memory problems when they wrote an array of bytes out that resulted from the above code, you may want to type out
     * the method name more explicitly to be sure that the right object is being implicitly constructed.
     */
    final class SkinTightBytesWritable(theBytes : BytesWritable) {
        def exactByteArray = theBytes.getBytes.slice(0, theBytes.getLength);
        def exactByteIterable = theBytes.getBytes.view(0, theBytes.getLength);
        def wholeBytesBuffer = theBytes.getBytes
    }
    implicit def __bw2b2(value : BytesWritable) : SkinTightBytesWritable = new SkinTightBytesWritable(value);

}
